//
// Copyright (c) 2005 BroadVision, Inc. All rights reserved.
//
// This software is copyrighted.  Under the copyright laws, this software
// may not be copied, in whole or in part, without prior written consent
// of BroadVision, Inc. or its assignees.  This software is provided under
// the terms of a license between BroadVision and the recipient, and its
// use is subject to the terms of that license.
//
// This software may be protected by one or more U.S. and International
// patents.  Certain applications of BroadVision One-To-One software are
// covered by U.S. patent 5,710,887.
//
// TRADEMARKS: BroadVision and BroadVision One-To-One are registered
// trademarks of BroadVision, Inc., in the United States and the European
// Community, and are trademarks of BroadVision, Inc., in other
// countries.  The BroadVision logo, is a trademark of BroadVision, Inc.,
// in the United States and other countries. Additionally, IONA and Orbix
// are trademarks of IONA Technologies, Ltd.  RSA, MD5, and RC2 are
// trademarks of RSA Data Security, Inc.
//

package com.broadvision.manage.common.tools.action.user;

import java.util.*;
import java.security.Principal;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.Globals;

import com.broadvision.portal.services.util.TransferBeanUtils;
import com.broadvision.portal.services.Channel;
import com.broadvision.portal.services.PortalVisitor;
import com.broadvision.web.util.ViewDynaBean;
import com.broadvision.system.accesscontrol.client.*;
import com.broadvision.visitor.client.VisitorManager;
import com.broadvision.visitor.client.Visitor;

import com.broadvision.manage.common.tools.user.UserProfile;
import com.broadvision.manage.tools.action.BaseAction;
import com.broadvision.web.action.Tab;
import com.broadvision.lictool2.LicToolWebApp;

import com.broadvision.visitor.client.VisitorGroupManager;
import com.broadvision.visitor.interfaces.VisitorGroup;


/**
 * Edits a user's roles
 */
public class RoleEditAction extends BaseAction {

  public static final String PAGE_TAB = "pagetab";
  public static final String VIEW_BEAN_NAME = "mtUserRoleView";
  public static final String DTO_BEAN_NAME  = "mtUserRoleDTO";
  public static final String DTO_GROUP_BEAN_NAME  = "mtGroupDTO";
  public static final String DTO_CHANNEL_BEAN_NAME  = "mtChannelDTO";
  public static final int  MAX_NUMBER_OF_GROUPS = 2147483646;

  public static final VisitorManager visitorMgr = new VisitorManager();

  /**
   * Implements the action for editing a user's roles.
   * <p> <p>
   * @param mapping <code>ActionMapping</code> object used to select this instance
   * @param form Optional <code>ActionForm</code> bean for this request (if any)
   * @param request <code>HttpServletRequest</code> object to process
   * @param response <code>HttpServletResponse</code> object to process
   * <p> <p>
   * @return <code>ActionForward</code> instance describing where and how
   * control should be forwarded, or null if the response has already been completed
   * <p> <p>
   * @throws Exception if an error occurs
   */
  public ActionForward processExecute(ActionMapping mapping,
                                      ActionForm form,
                                      HttpServletRequest request,
                                      HttpServletResponse response)
                               throws Exception
  {
    try {
      Tab tab = (Tab)request.getAttribute(PAGE_TAB);
      if (tab != null) {
        tab.disable();
      }    
      PortalVisitor agent = getPortalVisitor(request);
      ViewDynaBean view = new ViewDynaBean(VIEW_BEAN_NAME, mapping);
      request.setAttribute(VIEW_BEAN_NAME, view);
      long userId = ((Long) UserUtils.getP(form, "userId")).longValue();
      boolean isOrgAdmin = UserProfile.isOrganizationAdmin(getVisitor(request));
      boolean isUserAdmin = this.isUserInRole(this.getVisitor(request), UserProfile.USER_ADMIN);
 
	  if(!isUserAdmin && !isOrgAdmin && userId != (getVisitor(request)).getId()){
         request.setAttribute(Globals.ERROR_KEY, "error.group.noGroupAdmin");
		 return mapping.findForward("failure");
      }
	  if (isUserAdmin == false && userId != (getVisitor(request)).getId()) {
         // obtain all the related organization group assoicated to the visitor
         HashMap orgAdminsMap = new HashMap();
    
         AccessManager accessMgr = AccessManager.instance();
         List orgAdmins = accessMgr.getOwnerObjectsForPrincipal((Principal)getVisitor(request), UserProfile.ORGANIZATION_ADMIN);
         if (null != orgAdmins) {
               for (int j = 0; j < orgAdmins.size(); j++) {
               ACObjectID ac = (ACObjectID) orgAdmins.get(j);
               orgAdminsMap.put(ac.getObjectID().trim(), ac);
            }
         }
      	  
	  
         // obtain all the assoicated group to the user, obtained all the necessary path that associated to the 
         // organization related.
      VisitorGroup[] groups = VisitorGroupManager.findAllGroupsVisitorBelongsTo(userId, MAX_NUMBER_OF_GROUPS);
      boolean doFQN = false;
	  if (null != groups) {
         for (int i = 0; i < groups.length; i++) {
            if( doFQN == true)
	     	   break;
            VisitorGroup group = groups[i];
            List parents = new ArrayList(1);
            parents.add(group);
            parents.addAll(group.getParents(true));
            for (int j = 0; parents != null && j < parents.size(); j++) {
               VisitorGroup parent = (VisitorGroup)parents.get(j);
               if (orgAdminsMap.containsKey(parent.getFullyQualifiedName())) {
                  doFQN = true;
                  break;
               }
            }
         }
      }
	  // visitor is not userAdmin, user is not equal to visitor id, visitor doesn't
	  // have any member under his/her organization group
	  if ( !doFQN ) {
	     request.setAttribute(Globals.ERROR_KEY, "error.group.noGroupAdmin");
	     return mapping.findForward("failure");
      }
	  }
	  
	  UserProfile userProfile = new UserProfile(userId);
      userProfile.setServiceId(getServiceId(request));
      userProfile.edit();
      Visitor thisV = userProfile.getVisitor();
      String formattedName = UserUtils.getFormattedName(thisV, getResources(request), 
          getLocale(request));
      UserUtils.setP(view, "formattedName", formattedName);
      UserUtils.setP(view, "userAlias", thisV.getName());
      TransferBeanUtils.copyPropertiesToView(form, userProfile);
      
	  UserUtils.setP(view, "isOrgAdmin", new Boolean(isOrgAdmin && !isUserAdmin));
      int isPortal =  LicToolWebApp.getInstance().checkTag("portal.framework.basic");
      int isPortalFramework =  LicToolWebApp.getInstance().checkTag("portal.framework");
      int isCommerceShopping =  LicToolWebApp.getInstance().checkTag("commerce.shopping");
      int isContentServices =  LicToolWebApp.getInstance().checkTag("content.services");
      int isEmarketingServices =  LicToolWebApp.getInstance().checkTag("e-marketing.services.basic");
      UserUtils.setP(view, "isPortal", new Boolean((isPortal >= 0)));
      UserUtils.setP(view, "isContentServices", new Boolean((isContentServices >= 0) || (isPortalFramework >=0) || (isCommerceShopping >= 0)));
      UserUtils.setP(view, "isEmarketingServices", new Boolean((isEmarketingServices >= 0)));
      UserUtils.setP(form, "assignedRoles", userProfile.getAssignedRoles());
      List allRoles = UserProfile.getAllRoles(false);
      AccessManager accessMgr = AccessManager.instance();
      TreeMap tm = new TreeMap();
      if (null != allRoles) {
        for (int i = 0; i < allRoles.size(); i++) {
          UserRole ur = (UserRole) allRoles.get(i);
          String rName = ur.getName();
          ViewDynaBean oneDto = new ViewDynaBean(DTO_BEAN_NAME, mapping);
          UserUtils.setP(oneDto, "name", rName);      
          UserUtils.setP(oneDto, "friendlyName", ur.getFriendlyName());      
          UserUtils.setP(oneDto, "description", ur.getDescription());      
          List assocObjs = new ArrayList();
          if (rName.equals(UserProfile.ORGANIZATION_ADMIN)) {
            try {
              List orgAdmins = accessMgr.getOwnerObjectsForPrincipal((Principal)thisV, UserProfile.ORGANIZATION_ADMIN);
              if (null != orgAdmins) {
                String[] groupFQNs = new String[orgAdmins.size()];
                for (int j = 0; j < orgAdmins.size(); j++) {
                  ACObjectID ac = (ACObjectID) orgAdmins.get(j);
                  groupFQNs[j] = ac.getObjectID().trim();
                  ViewDynaBean oneGDto = new ViewDynaBean(DTO_GROUP_BEAN_NAME, mapping);
                  UserUtils.setP(oneGDto, "name", extractPathName(ac.getObjectID()));      
                  UserUtils.setP(oneGDto, "fqn", groupFQNs[j]); 
                  assocObjs.add(oneGDto);
                }
                UserUtils.setP(form, "groupFQNs", groupFQNs);      
              }
            }
            catch (Exception ex) {
            }
          }
          else if (rName.equals(UserProfile.CHANNEL_ADMIN)) {
            try {
              List channelAdmins = accessMgr.getOwnerObjectsForPrincipal((Principal) thisV, UserProfile.CHANNEL_ADMIN);
              if (null != channelAdmins) {
                Long[] channelIDs = new Long[channelAdmins.size()];
                for (int j = 0; j < channelAdmins.size(); j++) {
                  ACObjectID ac = (ACObjectID) channelAdmins.get(j);
                  Channel ch = (Channel) Channel.getObject(ac, agent);
                  if (ch.getServiceId() != getServiceId(request)) {
                     continue;
                  }
                  channelIDs[j] = new Long(ch.getId());
                  ViewDynaBean oneCDto = new ViewDynaBean(DTO_CHANNEL_BEAN_NAME, mapping);
                  UserUtils.setP(oneCDto, "id", channelIDs[j]);      
                  UserUtils.setP(oneCDto, "name", ch.getPathName()); 
                  assocObjs.add(oneCDto);
                }
                UserUtils.setP(form, "channelIDs", channelIDs);      
              }
              else {
                UserUtils.setP(form, "channelIDs", new Long[0]);      
              }
            }
            catch (Exception ex) {
            }
          }
          UserUtils.setP(oneDto, "associatedObjects", assocObjs);
          tm.put(rName, oneDto);
        }
      }
      List dtos = new ArrayList(tm.values());
      UserUtils.setP(view, "roleList", dtos);

    }
    catch (Exception ex) {
      request.setAttribute(Globals.ERROR_KEY, "error.application");
      return mapping.findForward("failure");
    }
    return mapping.findForward("success");
  }

  private String extractPathName(String fqn) {
    int i = fqn.indexOf(":");
    if (i < 0) {
      return fqn;
    }
    else {
      return fqn.substring(i + 1);
    }
  }
}
